#include "GBLabel.h"
#include "GBFont.h"
#include <gl.h>

using std::string;

#define SHADOW_OFFSET vec2(-5.0f, -2.5f)

GBLabel::GBLabel() 
: m_pFont(0), m_shadowOffset(SHADOW_OFFSET), m_shadowColor(COLOR_BLACK),
  m_bIsShadowed(false)
{

}

GBLabel::GBLabel(const char* szFontFace, const long pt, const Color fontColor) 
: m_shadowOffset(SHADOW_OFFSET), m_shadowColor(COLOR_BLACK), m_bIsShadowed(false)
{
	m_pFont = GBFontFactory::Instance()->GetFont(szFontFace, pt);
	m_color = fontColor;

	// Default Line Spacing
	if(m_pFont)
		m_lineSpacing = abs(m_pFont->GetPtSize() * 2.0f);
}

GBLabel::GBLabel(const std::string& szFontFace, const long pt, const Color fontColor)
: m_shadowOffset(SHADOW_OFFSET), m_shadowColor(COLOR_BLACK), m_bIsShadowed(false)
{
	m_pFont = GBFontFactory::Instance()->GetFont(szFontFace.c_str(), pt);
	m_color = fontColor;

	// Default Line Spacing
	if(m_pFont)
		m_lineSpacing = abs(m_pFont->GetPtSize() * 2.0f);
}

GBLabel::~GBLabel()
{

}

void GBLabel::Update(const float fTimeStep)
{
	GBWidget::Update(fTimeStep);


}

void GBLabel::Render()
{
	if(m_pFont == NULL || m_strings.empty()) return;

	float fNextX = 0.0f;

	unsigned stringCount = (unsigned)m_strings.size();
	for(unsigned i = 0; i < stringCount; i++)
	{
		const std::string& string = m_strings[i].string;
		matrix4& local = m_strings[i].local;
		
		// Offset according to TEXT SPACE
		if(m_AlignType == ALIGN_CENTER)
			fNextX = -m_pFont->GetTextWidth(string.c_str()) * 0.5f;
		else if(m_AlignType == ALIGN_RIGHT)
			fNextX = -m_pFont->GetTextWidth(string.c_str());

		local.MakeTranslation(m_local.wAxis().X() + fNextX, m_local.wAxis().Y() - (m_lineSpacing * i), m_local.wAxis().Z());
		local.RotPreZ(m_orientation.Z());

		glPushMatrix();
		{
			glMultMatrixf(local.M());

			if(m_bIsShadowed)
			{
				glPushMatrix();
				{
					glColor4fv(m_shadowColor.v);
					glTranslatef(m_shadowOffset.X(), m_shadowOffset.Y(), 0.0f);

					m_pFont->Print(m_strings[i].string.c_str());
				}
				glPopMatrix();
			}

			glColor4fv(GetColor().v);
			m_pFont->Print(m_strings[i].string.c_str());
		}
		glPopMatrix();
	}
}

void GBLabel::Copy(const GBWidget* pRef)
{
	// Copy over base material
	GBWidget::Copy(pRef);

	GBLabel* pLabel = (GBLabel*)pRef;

	// Copy over label material
    this->m_pFont = pLabel->m_pFont;
	this->m_strings = pLabel->m_strings;
	this->m_lineSpacing = pLabel->m_lineSpacing;
	this->m_bIsShadowed = pLabel->m_bIsShadowed;
	this->m_shadowColor = pLabel->m_shadowColor;
	this->m_shadowOffset = pLabel->m_shadowOffset;
}

void GBLabel::SetString(const char* szString, ...)
{
	if(szString == NULL) return;

	// Clear the old crap
	m_strings.clear();

	char szText[256];	// Holds Our String

	va_list	ap;	// Pointer To List Of Arguments

	va_start(ap, szString); // Parses The String For Variables
		vsprintf_s(szText, 256, szString, ap); // And Converts Symbols To Actual Numbers
	va_end(ap);// Results Are Stored In Text

	// New-Lines
	const char* start_line = szText;
	const char *c = szText;
	for(; *c; c++) 
	{
		if(*c== '\n') 
		{
			LabelString newString;

			for(const char *n = start_line; n < c; n++) 
				newString.string.append(1, *n);

			m_strings.push_back(newString);

			start_line = c + 1;
		}
	}

	if(start_line) 
	{
		LabelString newString;

		for(const char *n = start_line; n < c; n++) 
			newString.string.append(1, *n);

		m_strings.push_back(newString);
	}
}